package org.real.guetshop.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.real.guetshop.constant.MessageConstant;
import org.real.guetshop.constant.StatusConstant;
import org.real.guetshop.context.BaseContext;
import org.real.guetshop.exception.DeletionNotAllowedException;
import org.real.guetshop.mapper.ProductMapper;
import org.real.guetshop.pojo.dto.ProductDTO;
import org.real.guetshop.pojo.dto.ProductQueryDTO;
import org.real.guetshop.pojo.entity.Category;
import org.real.guetshop.pojo.entity.Product;
import org.real.guetshop.pojo.entity.RedisProduct;
import org.real.guetshop.pojo.vo.ProductVO;
import org.real.guetshop.result.PageResult;
import org.real.guetshop.service.ProductService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ProductServiceImpl implements ProductService {

    @Resource
    private ProductMapper productMapper;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    private final String CATEGORYKEY = "categoryList";
    private final String PRODUCT = "products";

    /**
     * 新增商品
     * @param productDTO
     */
    @Override
    public void addNewProduct(ProductDTO productDTO) {
        //属性拷贝
        Product product = new Product();
        BeanUtils.copyProperties(productDTO, product);
        product.setStoreId(BaseContext.getCurrentId());

        setCategory(product);

        product.setStatus(1);

        productMapper.insert(product);
    }

    /**
     * 修改商品
     * @param productDTO
     */
    @Override
    public void update(ProductDTO productDTO) {
        Product product = new Product();
        BeanUtils.copyProperties(productDTO, product);
        productMapper.updateProduct(product);
    }

    /**
     * 商品批量删除
     * @param ids
     */
    @Override
    @Transactional
    public void deleteBatch(List<Integer> ids) {
        //判断当前商品是否处于起售状态
        for (Integer id : ids) {

            Product product = productMapper.getById(id);
            if(Objects.equals(product.getStatus(), StatusConstant.ENABLE)){
                //当前商品处于起售中
                throw new DeletionNotAllowedException(MessageConstant.PRODUCT_ON_SALE);
            }
        }

        //根据商品id集合批量删除商品数据
        productMapper.deleteByIds(ids);
    }

    /**
     * 商家商品分页查询
     * @param productQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(ProductQueryDTO productQueryDTO) {
        //开始分页查询
        PageHelper.startPage(productQueryDTO.getPage(),productQueryDTO.getPageSize());
        productQueryDTO.setStoreId(BaseContext.getCurrentId());
        Page<Product> pageResult = productMapper.pageQuery(productQueryDTO);

        long total = pageResult.getTotal();
        List<Product> records = pageResult.getResult();

        return new PageResult(total,records);
    }

    /**
     * 根据分类id查询商品
     * @param categoryId
     * @return
     */
    @Override
    public List<Product> queryByCategoryId(Integer categoryId) {
        Product product = Product.builder()
                .categoryId(categoryId)
                .status(StatusConstant.ENABLE)
                .storeId(BaseContext.getCurrentId())
                .build();

        return productMapper.queryByCategoryId(product);
    }

    /**
     * 修改商品售卖状态
     * @param id
     * @param status
     */
    @Override
    public void editStatus(Integer id, Integer status) {
        productMapper.editStatus(id,status);
    }

    /**
     * 根据商店id查询商品
     * @param storeId
     * @return
     */
    @Override
    public List<Product> queryByStoreId(Integer storeId) {
        Product product = Product.builder()
                .storeId(storeId)
                .status(StatusConstant.ENABLE)
                .build();

        return productMapper.queryByStoreId(product);
    }

    /**
     * 根据分类id查询商品
     * @param product
     * @return
     */
    @Override
    public List<ProductVO> listByCategoryId(Product product) {
        List<Product> products = productMapper.list(product);
        List<ProductVO> productVOs = new ArrayList<>();
        // 遍历Product对象列表
        for (Product dbProduct : products) {
            // 为每个Product对象创建一个新的ProductVO对象
            ProductVO productVO = new ProductVO();
            // 复制属性
            BeanUtils.copyProperties(dbProduct, productVO);
            // 将ProductVO对象添加到列表中
            productVOs.add(productVO);
        }
        return productVOs;
    }

    /**
     * 获取分类列表
     * @return List
     */
    @Override
    public List<Category> getCategory() {
        return productMapper.getCategory();
    }

    /**
     * 获取热销商品
     * @return
     */
    @Override
    public List<ProductVO> getHot() {
        return productMapper.getHot();
    }

    /**
     * 用户商品分页查询
     * @param productQueryDTO
     * @return
     */
    @Override
    public PageResult pageQueryByUser(ProductQueryDTO productQueryDTO) {
        // 从 Redis 中获取整个商品列表
        List<RedisProduct> allProducts = (List<RedisProduct>) redisTemplate.opsForValue().get("Products");

        if (allProducts != null) {
            log.info("从redis中查询商品数据...");
            // 过滤和分页处理
            return filterAndPageProducts(allProducts, productQueryDTO);
        }

        // Redis 中没有数据，从数据库获取
        List<Product> allDbProducts = productMapper.findAllProducts();
        allProducts = new ArrayList<>();

        for (Product dbProduct : allDbProducts) {
            RedisProduct redisProduct = new RedisProduct();
            BeanUtils.copyProperties(dbProduct, redisProduct);
            allProducts.add(redisProduct);
        }

        // 将整个商品列表存入 Redis
        redisTemplate.opsForValue().set(PRODUCT, allProducts, 5, TimeUnit.DAYS);

        // 过滤和分页处理
        return filterAndPageProducts(allProducts, productQueryDTO);
    }

    private PageResult filterAndPageProducts(List<RedisProduct> allProducts, ProductQueryDTO productQueryDTO) {
        // 根据商品名称过滤
        if (productQueryDTO.getName() != null && !productQueryDTO.getName().isEmpty()) {
            String nameToMatch = productQueryDTO.getName().toLowerCase();
            allProducts = allProducts.stream()
                    .filter(product -> product.getName() != null && product.getName().toLowerCase().contains(nameToMatch))
                    .collect(Collectors.toList());
        }

        // 分页处理
        //TODO AI写的，还没优化
        int pageSize = productQueryDTO.getPageSize();
        int page = productQueryDTO.getPage();
        int fromIndex = (page - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, allProducts.size());
        List<RedisProduct> pagedProducts = allProducts.subList(fromIndex, toIndex);

        return new PageResult(allProducts.size(), pagedProducts);
    }

//    private List<Product> findAllProducts() {
//        // 从数据库中获取所有商品的逻辑
//        // 这里应该是调用数据库查询的方法
//        return productMapper.findAllProducts();
//    }

    /**
     * 将分类设置单独抽出来
     */
    private void setCategory(Product product){
        //商品类别查询，先从redis查询，如果redis为空再从数据库查询
        List<Category> categoryList = (List<Category>) redisTemplate.opsForValue().get(CATEGORYKEY);
        //TODO 第一句
//        ObjectMapper mapper = new ObjectMapper();

        if (categoryList == null || categoryList.isEmpty()) {
            //说明redis中没有数据，从数据库查找并且传入redis
            categoryList = productMapper.getCategory();
            //将分类列表传入缓存
            redisTemplate.opsForValue().set(CATEGORYKEY, categoryList,5 ,TimeUnit.DAYS);
        }

        //TODO 第二句
//        List<Category> categoryList1 = mapper.convertValue(categoryList, new TypeReference<List<Category>>() {});
        //查找商品相对应的分类
        for (Category category : categoryList) {
            if (product.getCategoryName().equals(category.getType())) {
                product.setCategoryId(category.getId());
            }
        }
    }
}
